package com.demo.common.util;


import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串处理工具类
 *
 * @author 刘洋
 */
public class StringUtil {

    /**
     * 日期格式字符串
     */
    public static final String DF_YMD = "yyyy-MM-dd";
    public static final String DFA_YMD = "yyyy/MM/dd";
    /**
     * 日期格式字符串
     */
    public static final String DF_YMD_24 = "yyyy-MM-dd HH:mm:ss";
    public static final String DFA_YMD_24 = "yyyy/MM/dd HH:mm:ss";

    /**
     * 日期格式字符串
     */
    public static final String DF_YMD_HM_24 = "yyyy-MM-dd HH:mm";
    /**
     * 月份格式字符串
     */
    public static final String DF_M_12 = "MM";
    /**
     * 日期格式字符串
     */
    public static final String DF_HM_24 = "HH:mm";
    /**
     * 日期格式字符串
     */
    public static final String DF_HMS_24 = "HH:mm:ss";
    /**
     * 日期格式字符串
     */
    public static final String DF_EEE_MMM = "EEE MMM dd HH:mm:ss zzz yyyy";
    /**
     * 驼峰分割符
     */
    public static final char UNDERLINE = '_';
    /**
     * 日时间戳
     */
    public static final int DAY_TIME_STAMP = 86400;

    /**
     * 月天数
     */
    public static final int MONTH_DAY = 30;

    /**
     * 空字符串
     */
    public static final String EMPTY = "";

    /**
     * 日志
     */
    private static final Logger logger = Logger.getLogger(StringUtil.class);

    /**
     * 判断字符串是否为空
     *
     * @param value
     * @return ture:为空 false:不为空
     */
    public static boolean isNullOrEmpty(String value) {
        return value == null || EMPTY.equals(value);
    }

    /**
     * 判断对象字符串是否为空
     *
     * @param
     * @return ture:为空 false:不为空
     */
    public static boolean isNullOrEmpty(Object value) {
        return value == null || EMPTY.equals(value);
    }

    /**
     * 判断字符串是否是数字
     *
     * @param
     * @return ture:是 false:否
     */
    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        return pattern.matcher(str).matches();
    }

    /**
     * 判断字符串是否是数字
     *
     * @param
     * @return ture:是 false:否
     */
    public static boolean isNumericS(String str) {
        if (StringUtil.isNullOrEmpty(str))
            return false;
        return str.matches("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$");
    }

    /**
     * 判断字符串是否是电话
     *
     * @param
     * @return ture:是 false:否
     */
    public static boolean isTelS(String tel){
        if (StringUtil.isNullOrEmpty(tel))
            return false;
        return tel.matches("^((0\\d{2,3}-?\\d{7,8})|(1[3567894]\\d{9}))$");
    }

    /**
     * 删除前后全角半角空格和tab
     *
     * @param value 处理值
     * @return 处理字符串
     */
    public static String delSpace(String value) {
        if (isNullOrEmpty(value)) {
            return EMPTY;
        }
        value = value.replaceAll("^[　 \t]+|[　 \t]+$", "");
        return value;
    }

    /**
     * 当字符串为null的时候、返回空字符串 ("") 。<br>
     * 不为null的场合返回传入字符串。
     *
     * @param str 处理值
     * @return 处理字符串
     */
    public static String nullToEmpty(String str) {
        return (str != null) ? str : EMPTY;
    }

    /**
     * 当对象为null的时候、返回空字符串 ("") 。<br>
     * 不为null的场合返回传入对象的字符串。
     *
     * @param obj 对象
     * @return 处理字符串
     */
    public static String nullToEmpty(Object obj) {
        return (obj != null) ? obj.toString() : EMPTY;
    }

    /**
     * 字符串转换成日期<br>
     * value为yyyy-MM-dd格式
     *
     * @param value 处理值
     * @return 转换字符串
     */
    public static Date strToDate(String value) {
        Date date = strToDate(value, DF_YMD);
        if (StringUtil.isNullOrEmpty(date)) {
            date = strToDate(value, DFA_YMD);
        }
        return date;
    }

    /**
     * 字符串转换成日期
     *
     * @param value  处理值
     * @param format 处理值日期格式
     * @return 转换字符串
     */
    public static Date strToDate(String value, String format) {
        Date result;
        if (value == null) {
            result = null;
        } else {
            SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance();
            sdf.applyPattern(format);
            sdf.setLenient(false);
            result = sdf.parse(value, new ParsePosition(0));
        }
        return result;
    }

    /**
     * 字符串转换成日期
     *
     * @param value  处理值
     * @param format 处理值日期格式 locale
     * @param locale locale
     * @return 转换字符串
     */
    public static Date strToDate(String value, String format, Locale locale) {
        if (value == null) {
            return null;
        }
        try {
            return new SimpleDateFormat(format, locale).parse(value);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 日期转换字符串<br>
     * 默认yyyy-MM-dd格式
     *
     * @param value 处理值
     * @return String 转换值
     */
    public static String dateFormat(Date value) {
        String str = dateFormat(value, DF_YMD);
        if (StringUtil.isNullOrEmpty(str)) {
            str = dateFormat(value, DFA_YMD);
        }
        return str;
    }

    /**
     * 日期转换字符串
     *
     * @param format 日期格式
     * @return String 转换值
     */
    public static String dateFormat(String format) {
        return dateFormat(new Date(), format);
    }

    /**
     * 日期转换字符串
     *
     * @param value  处理值
     * @param format 日期格式
     * @return String 转换值
     */
    public static String dateFormat(Date value, String format) {
        if (value == null || format == null) {
            return EMPTY;
        }
        SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance();
        sdf.applyPattern(format);
        return sdf.format(value);
    }

    public static String dateFormat(int value, String format) {
        long lt = new Long(value);
        return dateFormat(new Date(lt * 1000), format);
    }

    public static Long strToTimeStamp(Object obj) {
        Calendar calendar = Calendar.getInstance();
        if (!isNullOrEmpty(obj)) {
            if (obj.getClass().toString().indexOf("Date") > -1) {
                calendar.setTime((Date) obj);
            } else {
                String dt = (String) obj;
                dt = dt.replaceAll("/", "-");
                if (dt.length() == 19) {
                    calendar.setTime(strToDate(dt, DF_YMD_24));
                } else {
                    calendar.setTime(strToDate(dt));
                }
            }
        }
        Long timeStamp = calendar.getTimeInMillis() / 1000;
        //return Integer.parseInt(timeStamp.toString());
        return timeStamp;
    }

    public static Long strToTimeStamp() {
        return strToTimeStamp("");
    }

    //获取UnixTime 的整点时间
    public static Long dtToDaytamp(long dt) {
        return ((dt*1000)/(1000*3600*24)*(1000*3600*24) - TimeZone.getDefault().getRawOffset())/1000;
    }

    public static Long strToDayStamp() {
        return strToTimeStamp(dateFormat(new Date(), StringUtil.DF_YMD));
    }

    public static Long strToDayStamp(Long stamp) {
        return strToTimeStamp(dateFormat(new Date(stamp * 1000), DFA_YMD));
    }

    public static Long strToDayStartStamp() {
        return strToTimeStamp(dateFormat(new Date(), StringUtil.DFA_YMD));
    }

    public static Long timeToTimeStamp(String time) {
        String[] timeAry = time.split(":");
        Long rts = (Long.parseLong(timeAry[0]) * 60 + Long.parseLong(timeAry[1])) * 60;
        if (timeAry.length == 3) {
            rts += Long.parseLong(timeAry[2]);
        }
        return rts;
    }

    /**
     * 获取当前日期是星期几<br>
     *
     * @param obj
     * @return 当前日期是星期几
     */
    public static int getWeekOfDate(Object obj) {
        Calendar calendar = Calendar.getInstance();
        if (!isNullOrEmpty(obj)) {
            if (obj.getClass().toString().indexOf("Date") > -1) {
                calendar.setTime((Date) obj);
            } else if (obj.getClass().toString().indexOf("String") > -1) {
                calendar.setTime(strToDate((String) obj));
            } else if (obj.getClass().toString().indexOf("Integer") > -1 || obj.getClass().toString().indexOf("Long") > -1) {
                calendar.setTimeInMillis(Long.valueOf(obj.toString()) * 1000);
            }
        }
        int w = calendar.get(Calendar.DAY_OF_WEEK) - 1;

        return w == 0 ? 7 : w;
    }

    /**
     * 将整数转换成指定长度字符传，前面加0补位
     *
     * @param value  要转换的整数
     * @param length 长度
     * @return
     */
    public static String formatIntToString(Long value, Integer length) {
        if (value == null) {
            return null;
        }
        String strValue = value.toString();
        while (strValue.length() < length) {
            strValue = "0" + strValue;
        }
        return strValue;
    }

    /**
     * StringBuffer替换
     *
     * @param target 目标字符串
     * @param value  替换值
     * @param source 替换字符串
     * @return StringBuffer
     */
    public static StringBuffer strBufReplace(String target, String value, StringBuffer source) {
        if (source == null || target == null) {
            return source;
        }
        if (StringUtil.isNullOrEmpty(value)) {
            value = "";
        }

        int index = -1;

        while ((index = source.indexOf(target)) != -1) {
            source.replace(index, index + target.length(), value);
        }

        return source;
    }

    /**
     * 获取字符串中第N次出现的字符位置
     *
     * @param value     要获取的字符串
     * @param character 字符
     * @param pos       第几次出现
     * @return
     */
    public static int getCharacterPosition(String value, String character, int pos) {
        //这里是获取"subString"符号的位置
        Matcher slashMatcher = Pattern.compile(character).matcher(value);
        int resultPos = 0;
        int mIdx = 0;
        while (slashMatcher.find()) {
            mIdx++;
            //当"subString"符号第pos次出现的位置
            if (mIdx == pos) {
                resultPos = slashMatcher.start();
                break;
            }
        }
        return resultPos;
    }


    /**
     * 获取文件绝对路径中的文件扩展名
     *
     * @param path 文件绝对路径
     * @return
     */
    public static String getFileExt(String path) {
        String result = "";
        result = path.substring(path.lastIndexOf(".") + 1);
        return result;
    }

    public static String getFileNameWithoutExt(String path) {
        String result = "";
        result = path.substring(0, path.lastIndexOf("."));
        return result;
    }


    /**
     * 获取文件绝对路径中的文件名
     *
     * @param path 文件绝对路径
     * @return
     */
    public static String getFileName(String path) {
        String result = "";
        path = path.replace("\\", "/");
        result = path.substring(path.lastIndexOf("/") + 1);
        return result;
    }

    /**
     * 获取文件绝对路径中的绝对路径
     *
     * @param path 文件绝对路径
     * @return
     */
    public static String getFilePath(String path) {
        String result = "";
        path = path.replace("\\", "/");
        if (path.lastIndexOf("/") == -1) {
            return path;
        }
        result = path.substring(0, path.lastIndexOf("/"));
        return result;
    }

    /**
     * 获取UUID
     *
     * @return
     */
    public static String getUUID() {
        UUID uuid = UUID.randomUUID();
        String str = uuid.toString();
        // 去掉"-"符号  
        String temp = str.substring(0, 8) + str.substring(9, 13) + str.substring(14, 18) + str.substring(19, 23) + str.substring(24);
        return temp;
    }

    public static String writeToString(InputStream ins) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        int i = -1;
        while ((i = ins.read(b)) != -1) {
            out.write(b, 0, i);
        }
        ins.close();
        return new String(out.toByteArray(), "UTF-8");
    }


    /**
     * 两个时间实际相差的天数
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static double daysOfTwoDate(Date fromDate, Date toDate) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(fromDate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(toDate);
        long time2 = cal.getTimeInMillis();
        BigDecimal sw = new BigDecimal(time2 - time1).divide(new BigDecimal(1000 * 3600 * 24), 6, BigDecimal.ROUND_HALF_UP);
        return sw.doubleValue();
    }

    /**
     * 两个时间相差
     *
     * @param fromDate
     * @param toDate
     * @param format   (返回的是天/时/分/秒)
     * @return
     */
    public static double dateDiff(Date fromDate, Date toDate, String format) {
        long l = fromDate.getTime() - toDate.getTime();
        BigDecimal ll = new BigDecimal(l);
        BigDecimal sw = null;
        if (format.equals("d")) {
            sw = ll.divide(new BigDecimal(1000 * 3600 * 24), 6, BigDecimal.ROUND_HALF_UP);
        } else if (format.equals("h")) {
            sw = ll.divide(new BigDecimal(1000 * 3600), 6, BigDecimal.ROUND_HALF_UP);
        } else if (format.equals("m")) {
            sw = ll.divide(new BigDecimal(1000 * 60), 6, BigDecimal.ROUND_HALF_UP);
        } else if (format.equals("s")) {
            sw = ll.divide(new BigDecimal(1000), 6, BigDecimal.ROUND_HALF_UP);
        }
        return sw.doubleValue();
    }


    /**
     * 去掉字符串前后指定字符
     *
     * @param str
     * @param c
     * @return
     */
    public static String trimAll(String str, char c) {
        if (str.length() > 0) {
            String beginChar = str.substring(0, 1);
            while (beginChar.equalsIgnoreCase(String.valueOf(c))) {
                str = str.substring(1, str.length());
                beginChar = str.substring(0, 1);
            }

            String endChar = str.substring(str.length() - 1, str.length());
            while (endChar.equalsIgnoreCase(String.valueOf(c))) {
                str = str.substring(0, str.length() - 1);
                endChar = str.substring(str.length() - 1, str.length());
            }
        }
        return str;
    }


    /**
     * 获取两时间点的时间间隔差
     *
     * @param c1 c1.set(2014, 12, 17, 12, 24, 30);
     * @param c2 c2.set(2014, 12, 17, 13, 28, 54);
     * @return 00:01:04:24
     * @throws
     * @oaram format 00:00:00:00/00:00:00/00:00时分
     */
    public static String getElapsedTime(Calendar c1, Calendar c2, String format) {
        String formatTime = "";
        long difference = c2.getTimeInMillis() - c1.getTimeInMillis();
        long seconds = difference / 1000;
        long day = 0;
        long hour = 0;
        long minute = 0;
        long second = 0;
        minute = seconds / 60;
        second = seconds % 60;
        if (format.equals("00:00:00:00")) {
            if (minute / 60 > 0) {
                hour = minute / 60;
                minute = (minute - 60 == 1 ? 0 : minute % 60);
                if (hour / 24 > 0) {
                    day = hour / 24;
                    hour = (hour - 24 == 1 ? 0 : hour % 24);
                }
            }
            formatTime = "" + (day >= 10 ? day : "0" + day) + ":" + (hour >= 10 ? hour : "0" + hour) + ":" + (minute >= 10 ? minute : "0" + minute) + ":" + (second >= 10 ? second : "0" + second);
        } else if (format.equals("00:00:00")) {
            if (minute / 60 > 0) {
                hour = minute / 60;
                minute = (minute - 60 == 1 ? 0 : minute % 60);
            }
            formatTime = "" + (hour >= 10 ? hour : "0" + hour) + ":" + (minute >= 10 ? minute : "0" + minute) + ":" + (second >= 10 ? second : "0" + second);
        } else if (format.equals("00:00")) {
            if (minute / 60 > 0) {
                hour = minute / 60;
                minute = (minute - 60 == 1 ? 0 : minute % 60);
            }
            formatTime = "" + (hour >= 10 ? hour : "0" + hour) + ":" + (minute >= 10 ? minute : "0" + minute);
        } else {
            logger.error("can't solve the format info " + format);
        }

        return formatTime;
    }

    public static String getElapsedTime(Date d1, Date d2, String format) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(d1);
        Calendar c2 = Calendar.getInstance();
        c2.setTime(d2);
        return getElapsedTime(c1, c2, format);
    }

    /**
     * 判断是否是GUID
     *
     * @param guid str
     * @return
     */
    public static Boolean isGUID(String guid) {
        Boolean isGUID = true;
        try {
            UUID.fromString(guid);
        } catch (IllegalArgumentException e) {
            isGUID = false;
        }
        return isGUID;
    }

    /**
     * 将double值变更为“x时x分x秒”形式
     *
     * @param cpuUsage 单位小时的浮点数
     * @return
     */
    public static String hourFormat(double cpuUsage) {
        //转秒单位，取整数部分
        int sec = (new Double(cpuUsage * 60 * 60)).intValue();
        int hh = sec / 3600;
        int mmss = sec % 3600;
        int mm = mmss / 60;
        int ss = mmss % 60;

        String HH = hh < 10 ? "0" + hh : "" + hh;
        String MM = mm < 10 ? "0" + mm : "" + mm;
        String SS = ss < 10 ? "0" + ss : "" + ss;

        return HH + "时" + MM + "分" + SS + "秒";
    }

    /**
     * 打印异常的堆栈信息
     *
     * @param e 异常
     * @return String 异常信息
     */
    public static String outPutException(Exception e) {
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        e.printStackTrace(new PrintWriter(buf, true));
        String expMessage = buf.toString();
        return expMessage;
    }

    /**
     * AES加密
     *
     * @param msg 要加密的字符串
     * @return String 加密后的字符串

    public static String encrypt(String msg) {
    String ret = null;
    try {
    if (msg != null) {
    ret = AesUtil.encrypt(msg);
    }
    } catch (Exception e) {
    logger.error(StringUtil.outPutException(e));
    }//加解密字符串
    return ret;
    }
     */

    /**
     * AES解密
     *
     * @param msg 要解密的字符串
     * @return String 解密后的字符串

    public static String decrypt(String msg) {
    String ret = null;
    try {
    if (msg != null) {
    ret = AesUtil.decrypt(msg);
    }
    } catch (Exception e) {
    logger.error(StringUtil.outPutException(e));
    }//加解密字符串
    return ret;
    }
     */

    /**
     * 删除HTML标签
     */
    public static String delHTMLTag(String htmlStr) {
        if(isNullOrEmpty(htmlStr)){
            return "";
        }
        String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
        String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
        String regEx_html = "<[^>]+>"; //定义HTML标签的正则表达式
        String regEx_special = "\\&[a-zA-Z]{1,10};";// 定义一些特殊字符的正则表达式 如：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

        Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
        Matcher m_script = p_script.matcher(htmlStr);
        htmlStr = m_script.replaceAll(""); //过滤script标签

        Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
        Matcher m_style = p_style.matcher(htmlStr);
        htmlStr = m_style.replaceAll(""); //过滤style标签

        Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
        Matcher m_html = p_html.matcher(htmlStr);
        htmlStr = m_html.replaceAll(""); //过滤html标签

        Pattern p_special = Pattern.compile(regEx_special, Pattern.CASE_INSENSITIVE);
        Matcher m_special = p_special.matcher(htmlStr);
        htmlStr = m_special.replaceAll(""); // 过滤特殊标签

        return htmlStr.trim(); //返回文本字符串
    }

    /**
     * 驼峰格式字符串转换为下划线格式字符串
     *
     * @param param
     * @return
     */
    public static String camelToUnderline(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append(UNDERLINE);
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 下划线格式字符串转换为驼峰格式字符串
     *
     * @param param
     * @return
     */
    public static String underlineToCamel(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (c == UNDERLINE) {
                if (++i < len) {
                    sb.append(Character.toUpperCase(param.charAt(i)));
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 生成订单号
     */
    public static String getOrderNo() {
        int max = 9999;
        int min = 1000;
        Random random = new Random();
        int s = random.nextInt(max) % (max - min + 1) + min;
        return dateFormat(new Date(), "yyyyMMddHHmmss") + s;
    }

    /**
     * URL编码（utf-8）
     *
     * @param source
     * @return
     */
    public static String urlEncodeUTF8(String source) {
        String result = source;
        try {
            result = URLEncoder.encode(source, "utf-8");
        } catch (Exception e) {
            logger.error(outPutException(e));
        }
        return result;
    }

    public static Calendar getWeekFirst(int year, int week) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, 0, 1);
        int weeks = 0;
        if (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
            while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
                calendar.add(Calendar.DATE, 1);
            }
            weeks++;
        }
        while ((weeks = calendar.get(Calendar.WEEK_OF_YEAR)) != week) {
            calendar.add(Calendar.DATE, 7);
            //System.out.println(calendar.get(Calendar.WEEK_OF_YEAR));
        }
//		System.out.println(StringUtil.dateFormat(calendar.getTime(), StringUtil.DFA_YMD));
        return calendar;
    }

    //由出生日期获得年龄
    public static Float getAge(Long birthMillis, Long nowMillis) throws Exception {
        if (birthMillis == 0) {
            return 0f;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(nowMillis * 1000);
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        cal.setTimeInMillis(birthMillis * 1000);
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        float age = yearNow - yearBirth;
        age += Float.valueOf(monthNow - monthBirth) / 12;
        return Float.valueOf(new BigDecimal(age).setScale(1, BigDecimal.ROUND_HALF_UP).toString());
    }

    //字符串列表转换成以逗号隔开的拼接字符串
    public static String listToString(List dataList) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < dataList.size(); i++) {
            if (sb.length() > 0) {//该步即不会第一位有逗号，也防止最后一位拼接逗号！
                sb.append(",");
            }
            sb.append(dataList.get(i));
        }
        return sb.toString();
    }

    //根据起始日期计算日期列表
    public static List<String> findDates(String start, String end) throws ParseException {

        List<String> lDateStr = new ArrayList<>();

        //Calendar cal = Calendar.getInstance();
        //SimpleDateFormat sdf = new SimpleDateFormat(DFA_YMD);

        SimpleDateFormat sdf = new SimpleDateFormat(DFA_YMD);
        Date dBegin = sdf.parse(start);
        Date dEnd = sdf.parse(end);

        List<Date> lDate = findDates(dBegin, dEnd);

        sdf = new SimpleDateFormat(DFA_YMD);
        for (Date date : lDate) {
            //System.out.println(sdf.format(date));
            lDateStr.add(sdf.format(date));
        }
        return lDateStr;
    }

    //根据起始日期计算日期时间戳列表
    public static List<Long> findDateStamps(String start, String end) throws ParseException {
        List<Long> lDateStr = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat(DFA_YMD);
        Date dBegin = sdf.parse(start);
        Date dEnd = sdf.parse(end);
        List<Date> lDate = findDates(dBegin, dEnd);
        sdf = new SimpleDateFormat(DFA_YMD);
        for (Date date : lDate) {
            //System.out.println(sdf.format(date));
            lDateStr.add(StringUtil.strToTimeStamp(sdf.format(date)));
        }
        return lDateStr;
    }

    //根据起始日期计算日期列表
    public static List<Date> findDates(Date dBegin, Date dEnd) {
        List lDate = new ArrayList();
        lDate.add(dBegin);
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(dEnd);
        // 测试此日期是否在指定日期之后
        while (dEnd.after(calBegin.getTime())) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            lDate.add(calBegin.getTime());
        }
        return lDate;
    }

    /**
     * 时间戳转字符串
     *
     * @param stamp
     * @return
     */
    public static String StampToString(Long stamp) {
        return StampToString(stamp, StringUtil.DFA_YMD);
    }

    public static String StampToString(Long stamp, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(stamp * 1000));
    }

    public static String GetEndTime(String Start, Long Stamp) throws ParseException {
        SimpleDateFormat sd = new SimpleDateFormat(StringUtil.DFA_YMD_24);
        Date startDt = sd.parse(Start);
        long end = startDt.getTime() + Stamp * 1000;
        return StringUtil.StampToString(end / 1000, StringUtil.DF_HMS_24);
    }

    public static String aliasRule(Long institutionId) {
        return "_" + institutionId;
    }

    //手机号验证
    public static boolean isPhone(String phone) {
        String REGEX_MOBILE = "^((17[0-9])|(14[0-9])|(13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
        if (phone.length() != 11) {
            return false;
        } else {
            Pattern p = Pattern.compile(REGEX_MOBILE);
            Matcher m = p.matcher(phone);
            boolean isMatch = m.matches();
            return isMatch;
        }
    }


    /**
     * 根据开始日期 ，需要的天数 ，计算工作截止日期，并返回截止日期
     *
     * @param startDate
     * @param workDay
     * @param hour
     * @param second
     * @param minute
     * @return
     */
    public static Date getWorkDay(Date startDate, int workDay, int hour, int second, int minute) {
        Calendar c1 = Calendar.getInstance();
        c1.setTime(startDate);
        for (int i = 0; i < workDay; i++) {
            // 判断当天是否为周末，如果是周末加1
            /*if (Calendar.SATURDAY == c1.get(Calendar.SATURDAY) || Calendar.SUNDAY == c1.get(Calendar.SUNDAY)) {
                workDay = workDay + 1;
                c1.set(Calendar.DATE, c1.get(Calendar.DATE) + 1);
                continue;
            }*/
            c1.set(Calendar.DATE, c1.get(Calendar.DATE) + 1);
            // 当天数加1 判断是否为周末 如果是周末加1
           /* if (Calendar.SATURDAY == c1.get(Calendar.SATURDAY) || Calendar.SUNDAY == c1.get(Calendar.SUNDAY)) {
                workDay = workDay + 1;
                c1.set(Calendar.DATE, c1.get(Calendar.DATE) + 1);
                continue;
            }*/
        }
        return c1.getTime();

    }

    public static String[] union(String[] arr1, String[] arr2) {
        Set<String> set = new HashSet<String>();
        for (String str : arr1) {
            set.add(str);
        }
        for (String str : arr2) {
            set.add(str);
        }
        String[] result = {};
        return set.toArray(result);
    }

    public static String[] getJ(String[] arr1, String[] arr2) {
        List<String> rs = new ArrayList<>();
        Set<String> set = new HashSet<>(Arrays.asList(arr1.length > arr2.length ? arr1 : arr2));
        for (String i : arr1.length > arr2.length ? arr2 : arr1) {
            if (set.contains(i)) {
                rs.add(i);
            }
        }
        String[] arr = {};
        return rs.toArray(arr);
    }


    /**
     * 计算两个日期相差的月份数
     *
     * @param date1 日期1
     * @param date2 日期2
     * @return 相差的月份数
     * @throws ParseException
     */
    public static int countMonths(String date1, String date2) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(StringUtil.DFA_YMD);

        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();

        c1.setTime(sdf.parse(date1));
        c2.setTime(sdf.parse(date2));

        int year = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);

        //开始日期若小月结束日期
        if (year < 0) {
            year = -year;
            return year * 12 + c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
        }

        return year * 12 + c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
    }

    /**
     * 根据开始日期和月份数计算结束日期
     *
     * @param startDt
     * @param
     * @return
     */
    public static String countMonth(String startDt, int monthCount) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(StringUtil.DFA_YMD);
        Calendar c1 = Calendar.getInstance();
        c1.setTime(sdf.parse(startDt));
        int startMonth = c1.get(Calendar.MONTH) + 1;
        int endMonth = startMonth + monthCount;
        if (endMonth <= 12) {
            return c1.get(Calendar.YEAR) + "/" + endMonth + "/" + c1.get(Calendar.DAY_OF_MONTH);
        } else {
            int year = c1.get(Calendar.YEAR) + (endMonth - 1) / 12;
            int result = endMonth - (endMonth / 12) * 12;
            if (result == 0) {
                startMonth += 11;
                return String.valueOf(year) + "/" + startMonth + "/" + c1.get(Calendar.DAY_OF_MONTH);
            } else {
                return String.valueOf(year) + "/" + result + "/" + c1.get(Calendar.DAY_OF_MONTH);
            }
        }
    }

    public static String[] mergeAry(String[] x, String[] y) {
        List list = new ArrayList();
        for (String z : x) {
            if (Arrays.binarySearch(y, z) > -1) {
                list.add(z);
            }
        }
        return (String[]) list.toArray(new String[list.size()]);
    }

    /**
     * 逗号隔开字符串去重
     */
    public static String strAryFilter(String str) {
        String[] strAry = str.split(",");
        List<String> strList = new ArrayList<>();
        for (String ss : strAry) {
            if (!strList.contains(ss)) {
                strList.add(ss);
            }
        }
        String rtStr = "";
        for (String ss : strList) {
            rtStr += ss + ",";
        }
        if (!StringUtil.isNullOrEmpty(rtStr)) {
            rtStr = rtStr.substring(0, rtStr.length() - 1);
        }
        return rtStr;
    }

    public static List<LinkedHashMap> bulidLinepic(long startDt, long endDt) {
        List<LinkedHashMap> linePic = new LinkedList<>();
        for (Long i = startDt; i <= endDt; i += 86400) {
            LinkedHashMap temp = new LinkedHashMap();
            temp.put("peopleNum", (int) (Math.random() * 50));
            temp.put("day", i);
            linePic.add(temp);
        }
        return linePic;
    }

    public static List<Integer> getfiveNum() {
        Random random = new Random();

        List<Integer> numbers = new LinkedList<>();
        int sum = 0;

        while (true) {
            int n = random.nextInt(100);
            sum += n;
            numbers.add(n);

            if (numbers.size() > 5 || sum > 100) {
                numbers.clear();
                sum = 0;
            }

            if (numbers.size() == 5 && sum == 100) {
                break;
                //System.out.println(numbers);
            }
        }

        return numbers;
    }

    /**
     * 替换掉emoji表情
     *
     * @param source
     * @return mixed|string
     */
    public static String filterEmoji(String source) {
        if (StringUtils.isNotBlank(source)) {
            return source.replaceAll("[\\ud800\\udc00-\\udbff\\udfff\\ud800-\\udfff]", "*");
        } else {
            return source;
        }
    }

    /**
     * 数组对象转字符串数组
     */
    public static String[] listToStrAry(List<LinkedHashMap> listMap, String key) {
        List strs = new ArrayList();
        for (Map map : listMap) {
            if (!StringUtil.isNullOrEmpty(map.get(key))) {
                strs.add(map.get(key).toString());
            }
        }
        return (String[]) strs.toArray(new String[0]);
    }

    /**
     * 解码编号
     *
     * @param
     * @return
     */
    public static Map decodeCampusNo(String campusNo) {
        String[] nostrs = campusNo.split("@");
        Map map = new HashMap();
        map.put("suffix", nostrs[0]);
        map.put("campusId", nostrs[1]);
        return map;
    }

    /**
     * 将emoji标签转换成utf8字符集保存进数据库
     *
     * @param str 需要转换的字符串
     * @return
     */
    public static String emojiConvert(String str) {
        String patternString = "([\\x{10000}-\\x{10ffff}\\ud800-\\udfff])";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            try {
                matcher.appendReplacement(sb, "[[" + URLEncoder.encode(matcher.group(1), "UTF-8") + "]]");
            } catch (UnsupportedEncodingException e) {
                logger.error("emojiConvert error" + e.getMessage());
                return str;
            }
        }
        matcher.appendTail(sb);
        logger.debug("emojiConvert " + str + " to " + sb.toString() + ", len：" + sb.length());
        return sb.toString();
    }


    /**
     * 表情还原处理
     *
     * @param str
     * @return
     */
    public static String emojiRecovery(String str) {
        String patternString = "\\[\\[(.*?)\\]\\]";

        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(str);

        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            try {
                matcher.appendReplacement(sb,
                        URLDecoder.decode(matcher.group(1), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                logger.error("emojiRecovery error" + e.getMessage());
                return "";
            }
        }
        matcher.appendTail(sb);
        logger.debug("emojiRecovery " + str + " to " + sb.toString());
        return sb.toString();
    }

    /**
     * 时间正则匹配
     *
     * @param time
     * @return
     */
    public static String timeMatch(String time) {
        List<String> strs = new ArrayList<>();
        Pattern p = Pattern.compile("\\d{2}\\:\\d{2}");
        Matcher m = p.matcher(time);
        while (m.find()) {
            strs.add(m.group());
        }
        return strs.get(0);
    }

    /**
     * 获取LinkedHashMap的第1个元素的值
     * @param map
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> Map.Entry<K, V> getHead(LinkedHashMap<K, V> map) {
        return map.entrySet().iterator().next();
    }


    /**
     * 取得月第一天
     *
     * @return
     */
    public static long getFirstDateOfMonth() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR),cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0,0);
        cal.set(Calendar.DAY_OF_MONTH,cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        return (long)(cal.getTime().getTime()/1000);
    }

    /**
     * 取得月第一天
     *
     * @return
     */
    public static long getLastDateOfMonth() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR),cal.get(Calendar.MONDAY)-1, cal.get(Calendar.DAY_OF_MONTH), 0, 0,0);
        cal.set(Calendar.DAY_OF_MONTH,cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        return (long)(cal.getTime().getTime()/1000);
    }

    //获得本周一0点时间
    public static long getTimesWeekmorning(){
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR),cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0,0);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return (long) (cal.getTimeInMillis()/1000);
    }

    //获得本年第一天0点时间
    public static long getTimesYearmorning(){
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR),cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0,0);
        cal.set(Calendar.DAY_OF_YEAR, cal.getActualMinimum(Calendar.DAY_OF_YEAR));
        return (long) (cal.getTimeInMillis()/1000);
    }

    //获得去年第一天0点时间
    public static long getTimesLastYearmorning(){
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR)-1,cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0,0);
        cal.set(Calendar.DAY_OF_YEAR, cal.getActualMinimum(Calendar.DAY_OF_YEAR));
        return (long) (cal.getTimeInMillis()/1000);
    }

    /**
     * 获取某月得第一天
     * @param year 年
     * @param month 月
     * @return
     */
    public static Date getFirstDayOfMonth(int year, int month){
        Calendar c = new GregorianCalendar();

        c.set(year, month, 1);
        c.set(Calendar.HOUR, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);

        return c.getTime();
    }



    //本季度第一天
   public static long getFirstDayOfQuarter(){
       Calendar cal = Calendar.getInstance();
       int quarter=0;
       int month=0;
       if(cal.get(Calendar.MONTH)<=2){
           quarter=1;
       }else if(cal.get(Calendar.MONTH)>2&&cal.get(Calendar.MONTH)<=5){
           quarter=2;
       }else if(cal.get(Calendar.MONTH)>5&&cal.get(Calendar.MONTH)<=8){
           quarter=3;
       }else if(cal.get(Calendar.MONTH)>8&&cal.get(Calendar.MONTH)<=11){
           quarter=4;
       }
        switch (quarter) {
            case 1:
                month = 1-1;
                break;
            case 2:
                month = 4-1;
                break;
            case 3:
                month = 7-1;
                break;
            case 4:
                month = 10-1;
                break;
            default:
                month = cal.get(Calendar.MONTH);
                break;
        }

        return (long)(getFirstDayOfMonth(cal.get(Calendar.YEAR), month).getTime()/1000);
    }

    //本季度第一天
    public static long getLastDayOfQuarter(){
        Calendar cal = Calendar.getInstance();
        int quarter=0;
        int month=0;
        if(cal.get(Calendar.MONTH)<=2){
            quarter=1;
        }else if(cal.get(Calendar.MONTH)>2&&cal.get(Calendar.MONTH)<=5){
            quarter=2;
        }else if(cal.get(Calendar.MONTH)>5&&cal.get(Calendar.MONTH)<=8){
            quarter=3;
        }else if(cal.get(Calendar.MONTH)>8&&cal.get(Calendar.MONTH)<=11){
            quarter=4;
        }
        switch (quarter) {
            case 1:
                month = 1-4;
                break;
            case 2:
                month = 4-4;
                break;
            case 3:
                month = 7-4;
                break;
            case 4:
                month = 10-4;
                break;
            default:
                month = cal.get(Calendar.MONTH);
                break;
        }

        return (long)(getFirstDayOfMonth(cal.get(Calendar.YEAR), month).getTime()/1000);
    }

    public static List<Long> listStringToLong(List<String> inList){
        List<Long> iList =new ArrayList<Long>(inList.size());
        try{
            for(int i=0,j=inList.size();i<j;i++){
                iList.add(Long.parseLong(inList.get(i)));
            }
        }catch(Exception  e){
        }
        return iList;
    }

}
